#include"StdMsgQueue.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/msg.h>


struct StdMsgQueue
{
    int msgId;
};

MsgQ *MsgQueueInit(const char *pathname, int proj_id)
{
    MsgQ *m = (MsgQ *)malloc(sizeof(MsgQ));
    if(m==NULL)
    {
        perror("malloc");
        return NULL;
    }
    int key = ftok(pathname, proj_id);
    if(key==-1)
    {
        perror("ftok");
        free(m);
        return NULL;
    }
    m->msgId= msgget(key, IPC_CREAT | 0777);
    if(m->msgId<0)
    {
        perror("msgget");
        free(m);
        return NULL;
    }
    return m;
}

bool ReadFromMsgQ(MsgQ *q, long type, void *p ,size_t size)
{
    void *newP = malloc(size + 8);
    if(newP==NULL)
    {
        perror("malloc:");
        return NULL;
    }
    if(msgrcv(q->msgId,newP,size,type,0)<0)
    {
        perror("msgrcv");
        free(newP);
        return false;
    }
    memcpy(p, newP + 8, size);
    return true;
}

bool WriteToMsgQ(MsgQ *q, long type, void *p, size_t size)
{
    //拼接类型和内容
    void *newP = malloc(size + 8);
    if(newP==NULL)
    {
        perror("malloc:");
        return NULL;
    }
    memcpy(newP, &type, 8);
    memcpy(newP + 8, p, size);

    if (msgsnd(q->msgId,newP,size,0)<0)
    {
        perror("msgsnd");
        free(newP);
        return false;
    }
    free(newP);
    return true;
}

void ClearMsgQ(MsgQ *q)
{
    if(msgctl(q->msgId,IPC_RMID,NULL)!=0)
    {
        perror("msgctl RMID");
    }
    free(q);
}
